libobs_simple\sources\linux\sources/
pipewire_capture.rs1use libobs_simple_macro::{obs_object_builder, obs_object_updater};
2use libobs_wrapper::{
3 data::ObsDataGetters,
4 run_with_obs,
5 sources::{ObsSourceBuilder, ObsSourceRef},
6 unsafe_send::Sendable,
7 utils::{traits::ObsUpdatable, ObsError},
8};
9
10use crate::sources::macro_helper::define_object_manager;
11
12#[derive(Clone, Copy, Debug, PartialEq, Eq)]
13pub enum ObsPipeWireSourceType {
15 DesktopCapture,
17 CameraCapture,
19}
20#[obs_object_builder("pipewire-desktop-capture-source")]
41pub struct PipeWireDesktopCaptureSourceBuilder {
42 #[obs_property(type_t = "string", settings_key = "RestoreToken")]
44 restore_token: String,
45
46 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
48 show_cursor: bool,
49}
50
51#[obs_object_updater("pipewire-desktop-capture-source", ObsSourceRef)]
52pub struct PipeWireDesktopCaptureSourceUpdater {
53 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
55 show_cursor: bool,
56}
57
58#[obs_object_builder("pipewire-window-capture-source")]
59pub struct PipeWireWindowCaptureSourceBuilder {
60 #[obs_property(type_t = "string", settings_key = "RestoreToken")]
62 restore_token: String,
63
64 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
66 show_cursor: bool,
67}
68
69#[obs_object_updater("pipewire-window-capture-source", ObsSourceRef)]
70pub struct PipeWireWindowCaptureSourceUpdater {
71 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
73 show_cursor: bool,
74}
75
76#[obs_object_builder("pipewire-screen-capture-source")]
77pub struct PipeWireScreenCaptureSourceBuilder {
79 #[obs_property(type_t = "string", settings_key = "RestoreToken")]
81 restore_token: String,
82
83 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
85 show_cursor: bool,
86}
87
88#[obs_object_updater("pipewire-screen-capture-source", ObsSourceRef)]
89pub struct PipeWireScreenCaptureSourceUpdater {
91 #[obs_property(type_t = "bool", settings_key = "ShowCursor")]
93 show_cursor: bool,
94}
95
96define_object_manager!(
97 #[derive(Debug)]
98 struct PipeWireCameraSource("pipewire-camera-source") for ObsSourceRef {
103 #[obs_property(type_t = "string")]
105 camera_id: String,
106
107 #[obs_property(type_t = "string")]
109 video_format: String,
110
111 #[obs_property(type_t = "string")]
113 resolution: String,
114
115 #[obs_property(type_t = "string")]
117 framerate: String,
118 }
119);
120
121pub trait PipeWireSourceExtTrait {
123 fn get_restore_token(&self) -> Result<Option<String>, ObsError>;
129}
130
131impl PipeWireSourceExtTrait for ObsSourceRef {
132 fn get_restore_token(&self) -> Result<Option<String>, ObsError> {
133 if self.id() != "pipewire-desktop-capture-source"
134 && self.id() != "pipewire-window-capture-source"
135 && self.id() != "pipewire-screen-capture-source"
136 {
137 return Err(ObsError::InvalidOperation(format!("Can't call 'get_restore_token' on a source of id {}. Expected 'pipewire-desktop-capture-source', 'pipewire-window-capture-source' or 'pipewire-screen-capture-source'", self.id())));
138 }
139
140 let source_ptr = Sendable(self.as_ptr());
141 run_with_obs!(self.runtime(), (source_ptr), move || unsafe {
142 libobs::obs_source_save(source_ptr);
143 })?;
144
145 let settings = self.get_settings()?;
146 let token = settings.get_string("RestoreToken")?;
147 Ok(token)
148 }
149}
150
151impl PipeWireDesktopCaptureSourceBuilder {
152 pub fn with_cursor(self) -> Self {
154 self.set_show_cursor(true)
155 }
156}
157
158impl PipeWireCameraSourceBuilder {
159 pub fn set_resolution_values(self, width: u32, height: u32) -> Self {
161 self.set_resolution(format!("{}x{}", width, height))
162 }
163
164 pub fn set_framerate_values(self, num: u32, den: u32) -> Self {
166 self.set_framerate(format!("{}/{}", num, den))
167 }
168}
169
170impl ObsSourceBuilder for PipeWireDesktopCaptureSourceBuilder {}
171impl ObsSourceBuilder for PipeWireWindowCaptureSourceBuilder {}
172impl ObsSourceBuilder for PipeWireScreenCaptureSourceBuilder {}
173impl ObsSourceBuilder for PipeWireCameraSourceBuilder {}